using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using DevExpress.XtraGrid.Views.BandedGrid;
using DevExpress.Utils;

namespace Demo
{
    internal static class GridDataHelper
    {
        private static readonly Dictionary<string, string> ColumnNameMappings = new()
        {
            { "参数编号", "ParameterNumber" },
            { "主试名字", "MainTesterName" },
            { "儿童名字", "ChildName" },
            { "测试日期", "TestDate" },
            { "出生日期", "BirthDate" },
            { "所在年级", "Grade" },
            { "家长教育程度", "ParentEducation" },
            { "电话号码", "PhoneNumber" },
            { "电子游戏", "VideoGame" },
            { "联系地址", "Address" },
            { "备注资料", "Remarks" },
            { "儿童性别", "ChildGender" },
            { "用手习惯", "HandPreference" },
            { "积木", "Blocks" },
            { "常识", "Comprehension" },
            { "矩阵推理", "MatrixReasoning" },
            { "找虫", "BugSearch" },
            { "图片记忆", "PictureMemory" },
            { "类同", "Similarities" },
            { "图书概念", "PictureConcepts" },
            { "画消", "Cancellation" },
            { "动物家园", "AnimalHome" },
            { "拼图", "Puzzle" },
            { "动物译码", "AnimalCoding" },
            { "理解", "Understanding" },
            { "指认图片", "PictureRecognition" },
            { "图片命名", "PictureNaming" },
            { "随机画消", "RandomCancellation" },
            { "有序画消", "OrderedCancellation" },
            { "信赖水平", "ConfidenceLevel" },
            { "统计显著性水准", "StatisticalSignificance" },
            { "比较基础", "ComparisonBasis" },
            { "计算方法1", "CalculationMethod" },
            { "计算方法2", "CalculationMethod2" },
            { "文件路径", "FilePath" }
        };

        private static readonly HashSet<Type> AllowedExportTypes = new()
        {
            typeof(string),
            typeof(bool),
            typeof(byte), typeof(sbyte),
            typeof(short), typeof(ushort),
            typeof(int), typeof(uint),
            typeof(long), typeof(ulong),
            typeof(float), typeof(double), typeof(decimal),
            typeof(DateTime),
            typeof(Guid)
        };

        internal static void PrepareDataTable(DataTable table)
        {
            NormalizeColumnNames(table);
            EnsureExportFriendlyColumnTypes(table);
        }

        internal static string GetCellString(BandedGridView view, string fieldName)
        {
            return GetCellString(view, view.FocusedRowHandle, fieldName);
        }

        internal static string GetCellString(BandedGridView view, int rowHandle, string fieldName)
        {
            if (rowHandle < 0)
            {
                return string.Empty;
            }

            var text = view.GetRowCellDisplayText(rowHandle, fieldName);
            if (string.IsNullOrWhiteSpace(text))
            {
                var rawValue = view.GetRowCellValue(rowHandle, fieldName);
                text = rawValue?.ToString() ?? string.Empty;
            }

            return string.IsNullOrWhiteSpace(text) ? string.Empty : text.Trim();
        }

        private static void NormalizeColumnNames(DataTable table)
        {
            foreach (var mapping in ColumnNameMappings)
            {
                if (table.Columns.Contains(mapping.Key) && !table.Columns.Contains(mapping.Value))
                {
                    table.Columns[mapping.Key].ColumnName = mapping.Value;
                }
            }
        }

        private static void EnsureExportFriendlyColumnTypes(DataTable table)
        {
            var columns = table.Columns.Cast<DataColumn>().ToList();
            foreach (var column in columns)
            {
                var underlying = Nullable.GetUnderlyingType(column.DataType) ?? column.DataType;

                if (AllowedExportTypes.Contains(underlying) || column.DataType == typeof(byte[]))
                {
                    continue;
                }

                if (underlying.IsEnum)
                {
                    ConvertColumnToString(table, column);
                    continue;
                }

                ConvertColumnToString(table, column);
            }
        }

        private static void ConvertColumnToString(DataTable table, DataColumn column)
        {
            var newColumn = new DataColumn(column.ColumnName + "_text", typeof(string));
            table.Columns.Add(newColumn);

            foreach (DataRow row in table.Rows)
            {
                var value = row[column];
                row[newColumn] = value?.ToString() ?? string.Empty;
            }

            var originalName = column.ColumnName;
            var ordinal = column.Ordinal;
            table.Columns.Remove(column);
            newColumn.SetOrdinal(ordinal);
            newColumn.ColumnName = originalName;
        }
    }
}
